/********************************Copyright (c)**********************************\
**
**                   (c) Copyright 2025, Main, China, QD.
**                           All Rights Reserved
**
**                                 By(wo4fisher)
**                           http://www.wo4fisher.com
**
**----------------------------------文件信息------------------------------------
** 文件名称: sensor.c
** 创建人员: wht
** 创建日期: 2025-10-15
** 文档描述: 
**
**----------------------------------版本信息------------------------------------
** 版本代号: V0.1
** 版本说明: 初始版本
**
**------------------------------------------------------------------------------
\********************************End of Head************************************/
#include "sensor.h"
#include "FreeRTOS.h"
#include "task.h"

/* 私有类型定义 --------------------------------------------------------------*/
/**
 * @brief 传感器滤波状态结构体
 */
typedef struct {
    Sensor_Status current_status;       /*!< 当前状态 */
    Sensor_Status filtered_status;      /*!< 滤波后状态 */
    uint8_t stable_count;               /*!< 状态稳定计数 */
} Sensor_Filter_TypeDef;

/* 私有变量 ------------------------------------------------------------------*/
static Sensor_Filter_TypeDef door_filter = {SENSOR_STATUS_INACTIVE, SENSOR_STATUS_INACTIVE, 0};
static Sensor_Filter_TypeDef vibration_filter = {SENSOR_STATUS_INACTIVE, SENSOR_STATUS_INACTIVE, 0};

/* 私有函数声明 ------------------------------------------------------------*/
static void Sensor_Filter_Process(Sensor_Filter_TypeDef *filter, Sensor_Status raw_status);

/* 函数定义 ------------------------------------------------------------------*/

/**
 * @brief 传感器初始化函数
 * @retval None
 */
void Sensor_Init(void)
{
    /* GPIO已在HAL库初始化中配置，此处可添加其他初始化代码 */
    door_filter.current_status = SENSOR_STATUS_INACTIVE;
    door_filter.filtered_status = SENSOR_STATUS_INACTIVE;
    door_filter.stable_count = 0;
    
    vibration_filter.current_status = SENSOR_STATUS_INACTIVE;
    vibration_filter.filtered_status = SENSOR_STATUS_INACTIVE;
    vibration_filter.stable_count = 0;
}

/**
 * @brief 检测门开关状态(带滤波)
 * @return Sensor_Status 滤波后的传感器状态
 *         - SENSOR_STATUS_ACTIVE: 门打开（高电平）
 *         - SENSOR_STATUS_INACTIVE: 门关闭（低电平）
 */
Sensor_Status Sensor_Door_Check(void)
{
    Sensor_Status raw_status;
    
    // 读取原始状态
    if (HAL_GPIO_ReadPin(DOOR_OPEN_GPIO_Port, DOOR_OPEN_Pin) == GPIO_PIN_SET)
    {
        raw_status = SENSOR_STATUS_ACTIVE;
    }
    else
    {
        raw_status = SENSOR_STATUS_INACTIVE;
    }
    
    // 软件滤波处理
    Sensor_Filter_Process(&door_filter, raw_status);
    
    return door_filter.filtered_status;
}

/**
 * @brief 检测振动传感器状态(带滤波)
 * @return Sensor_Status 滤波后的传感器状态
 *         - SENSOR_STATUS_ACTIVE: 检测到振动（高电平）
 *         - SENSOR_STATUS_INACTIVE: 无振动检测（低电平）
 */
Sensor_Status Sensor_Vibration_Check(void)
{
    Sensor_Status raw_status;
    
    // 读取原始状态
    if (HAL_GPIO_ReadPin(VIB_CHECK_GPIO_Port, VIB_CHECK_Pin) == GPIO_PIN_SET)
    {
        raw_status = SENSOR_STATUS_ACTIVE;
    }
    else
    {
        raw_status = SENSOR_STATUS_INACTIVE;
    }
    
    // 软件滤波处理
    Sensor_Filter_Process(&vibration_filter, raw_status);
    
    return vibration_filter.filtered_status;
}

/**
 * @brief 传感器滤波处理函数
 * @param filter 指向滤波结构体的指针
 * @param raw_status 原始传感器状态
 * @retval None
 */
static void Sensor_Filter_Process(Sensor_Filter_TypeDef *filter, Sensor_Status raw_status)
{
    // 软件滤波处理
    if (raw_status != filter->current_status)
    {
        filter->current_status = raw_status;
        filter->stable_count = 0;  // 状态变化，重新计数
    }
    else
    {
        if (filter->stable_count < DEBOUNCE_CHECK_COUNT)
        {
            filter->stable_count++;
            
            // 连续稳定达到要求次数后更新滤波状态
            if (filter->stable_count >= DEBOUNCE_CHECK_COUNT)
            {
                filter->filtered_status = filter->current_status;
            }
        }
    }
}

/**
 * @brief 传感器滤波任务
 * @param argument 任务参数
 */
void Sensor_Filter_Task(void const *argument)
{
    while (1)
    {
        // 定期执行滤波检测
        Sensor_Door_Check();
        Sensor_Vibration_Check();
        
        // 延时一段时间再次检测
        vTaskDelay(pdMS_TO_TICKS(DEBOUNCE_CHECK_PERIOD));
    }
}
/********************************End of File************************************/